//
//  LoginManager.m
//  bsl-sdk
//
//  Created by Fanty on 13-12-1.
//
//

#import "CubeModuleManager.h"
#import "MainModule.h"
#import <ChamleonSDK/CApplication.h>
#import "ASIHTTPRequest.h"
#import "ApiConstant+Cube.h"
#import "DataCenter.h"
#import "DataCenter+Cube.h"
#import "CubeModuleParser.h"
#import "AsyncTask.h"
#import "CubesModel.h"
#import "IsolatedStorageFile(CubeLogic).h"
#import "CubeModuleWorkTask.h"
#import "DataCenter+Cube.h"
#import "CubeModule.h"
#import "LocalModelParser.h"
#import "BSLCubeConstant.h"
#import "SnapshotParser.h"

@interface CubeModuleManager()
-(AsyncTask*) loadRemoteServerMouduleList;
-(void)setTaskNil;
-(void)saveLocalModuleList;
@end

@implementation CubeModuleManager

-(id)init{
    self=[super init];
    
    if(self){
        asyncs=[[NSMutableArray alloc] initWithCapacity:2];
    }
    
    return self;
}

-(AsyncTask*) loadRemoteServerMouduleList{
    
    MainModule* mainModule=(MainModule*)[[CApplication sharedApplication] moduleForIdentifier:@"bsl.main"];
    CubeModule* module=(CubeModule*)[[CApplication sharedApplication] moduleForIdentifier:@"bsl.cube"];

    NSString* sessionKey=[[DataCenter defaultCenter].dictonary objectForKey:@"bsl-sessionkey"];
    
    NSString* username=module.username;


    ASIHTTPRequest* request=[ASIHTTPRequest requestWithURL:[[ApiConstant defaultConstant] moduleListURL:sessionKey username:username]];
    CubeModuleParser* parser=[[CubeModuleParser alloc] init];

    return [mainModule asyncWithOperation:request parser:parser];

}

-(void)setTaskNil{
    syncTask=nil;
}

-(void)syncModuleList:(void (^)(BOOL success))callback{
    [syncTask cancel];
    syncTask=[self loadRemoteServerMouduleList];
    __block CubeModuleManager* objSelf=self;
    __block AsyncTask* __syncTask=syncTask;
    [syncTask setFinishBlock:^{
        
        BOOL ret = NO;
        if([__syncTask result]!=nil){
            ret = YES;
            //服务器返回的原始数据
            NSArray* remoteServiceList = (NSArray*)[__syncTask result];
            
            //本地已安装的模块
            if([DataCenter defaultCenter].installMoudules==nil){
                NSMutableArray* array=[[NSMutableArray alloc] init];
                [DataCenter defaultCenter].installMoudules=array;
            }
            NSMutableArray* installModuleList = [DataCenter defaultCenter].installMoudules;
            
            //本地的service模块全部替换成最新模块
            if([remoteServiceList count]>0)
                [DataCenter defaultCenter].serviceModules = remoteServiceList;
            
            //同步已安装列表
            //临时遍历用列表，为了线程安全
            NSArray* temModuleList =[NSArray arrayWithArray:installModuleList];
            remoteServiceList=[DataCenter defaultCenter].serviceModules;
            
            for(CubeModel* iModule in temModuleList){
                
                CubeModel* serviceModel=nil;
                for(CubeModel* _serviceModel in remoteServiceList){
                    if([_serviceModel.identifier isEqualToString:iModule.identifier]){
                        serviceModel=_serviceModel;
                        break;
                    }
                }
                
                if (serviceModel==nil){
                    //服务器更改了关联关系，已安装模块列表得删除该模块
                    [installModuleList removeObject:iModule];
                }
                else{
                    //版本相同，则属性覆盖
                    if (iModule.build == serviceModel.build){
                        iModule.autoDownload = serviceModel.autoDownload;
                        iModule.bundle = serviceModel.bundle;
                        iModule.category = serviceModel.category;
                        iModule.hidden = serviceModel.hidden;
                        iModule.isAutoShow = serviceModel.isAutoShow;
                        iModule.local = serviceModel.local;
                        iModule.name = serviceModel.name;
                        iModule.releaseNote = serviceModel.releaseNote;
                        iModule.showIntervalTime = serviceModel.showIntervalTime;
                        iModule.sortingWeight = serviceModel.sortingWeight;
                        iModule.hasPrivileges = serviceModel.hasPrivileges;
                    }
                    else if (iModule.build < serviceModel.build)
                    {
                        //版本不同，应用设置为可更新
                        iModule.status = CubeMoudleStatusCanUpdate;
                    }
                }
            }
            
            //本地模块不需要安装，直接加进已安装列表中
            for (CubeModel* serviceModel in remoteServiceList){
                if ([serviceModel.local length]>0){
                    BOOL isExistInstallModel=NO;
                    for (CubeModel*installModel in installModuleList){
                        if([installModel.identifier isEqualToString:serviceModel.identifier]){
                            isExistInstallModel=YES;
                            break;
                        }
                    }
                    if(!isExistInstallModel)
                        [installModuleList addObject:serviceModel];
                    
                }
            }
            
            //保存至本地文件系统
            [objSelf saveLocalModuleList];
        }
        else{
            ret = NO;
        }
        [objSelf setTaskNil];

        if(callback!=nil)
            callback(ret);
    }];
}

-(AsyncTask*)loadSnapshotByIdentify:(NSString*)identifier version:(NSString*)version{
    MainModule* mainModule=(MainModule*)[[CApplication sharedApplication] moduleForIdentifier:@"bsl.main"];
    
    ASIHTTPRequest* request=[ASIHTTPRequest requestWithURL:[[ApiConstant defaultConstant] snapshotURL:identifier version:version]];
    SnapshotParser* parser=[[SnapshotParser alloc] init];
    
    return [mainModule asyncWithOperation:request parser:parser];

}

-(void)loadLocalModuleList{
    
    @autoreleasepool {
        LocalModelParser* localParser=[[LocalModelParser alloc] init];
        NSString* file=[IsolatedStorageFile localModelInfoFile];
        NSData* data=[[NSData alloc] initWithContentsOfFile:file];
        [localParser parse:data];
        [DataCenter defaultCenter].localModules=[localParser getResult];
    }
    
    CubeModuleParser* parser=[[CubeModuleParser alloc] init];

    @autoreleasepool {
        CubeModule* module=(CubeModule*)[[CApplication sharedApplication] moduleForIdentifier:@"bsl.cube"];

        NSString* username=module.username;
        NSString* file=[IsolatedStorageFile localMoudlelistDirectory:username];
        NSData* data=[[NSData alloc] initWithContentsOfFile:file];
        [parser parse:data];
    
    }
    
    [DataCenter defaultCenter].installMoudules=nil;
    NSMutableArray* list=[parser getResult];
        //如果某些模块未下载完成，则更新的保留，未下载的移除
    for (int i = 0; i < [list count]; i++){
            CubeModel* module =[list objectAtIndex:i];
        if ([module.local length]>0 || module.status == CubeMoudleStatusUpdating || module.status==CubeMoudleStatusCanUpdate){
                module.status = CubeMoudleStatusFinish;
            }
            else if (module.status != CubeMoudleStatusFinish){
                [list removeObjectAtIndex:i];
                i--;
            }
        }
    [DataCenter defaultCenter].installMoudules=list;
}

-(void)saveLocalModuleList{
    
    @autoreleasepool {
        NSString* json=[CubeModuleParser parserJSONFromArray:[DataCenter defaultCenter].installMoudules showOutputIcon:NO];
        CubeModule* module=(CubeModule*)[[CApplication sharedApplication] moduleForIdentifier:@"bsl.cube"];

        NSString* username=module.username;
        NSString* file=[IsolatedStorageFile localMoudlelistDirectory:username];
        [json writeToFile:file atomically:YES encoding:NSUTF8StringEncoding error:nil];
    }
}


-(CubeModel*)findDownloadingCubeModule:(NSString*)identifier{
    for(CubeModuleWorkTask* task in asyncs){
        if ([task.cubeModel.identifier isEqualToString:identifier]){
                return task.cubeModel;
        }
    }
    return nil;
}


-(void)cancel{
    for(CubeModuleWorkTask* async in asyncs){
        async.callback=nil;
        [async cancel];
    }
    [asyncs removeAllObjects];
}

-(int)downloadCount{
    return [asyncs count];
}

-(void)installModule:(NSString*)identifier{
    NSMutableArray* installMoudules = [[DataCenter defaultCenter] installMoudules];
    for (CubeModel* model in installMoudules){
        if ([model.identifier isEqualToString:identifier]){
            return;
        }
    }
    
    NSArray* serviceModules = [[DataCenter defaultCenter] serviceModules];
    
    for (CubeModel* model in serviceModules){
        if ([model.identifier isEqualToString:identifier]){
            model.status = CubeMoudleStatusInstalling;
            model.downloadedProcess = 0;
            model.downloadedTotalCount=100;
            [installMoudules addObject:model];
            [self saveLocalModuleList];
            CubeModuleWorkTask* async = [[CubeModuleWorkTask alloc] init];
            async.action = CubeModuleWorkTaskActionInstall;
            async.callback = self;
            async.cubeModel = model;
            [asyncs addObject:async];
            async = nil;
           
            break;
        }
    }
    
    if (!asyncIsDownloaded){
        asyncIsDownloaded = YES;
        CubeModuleWorkTask* async=[asyncs objectAtIndex:0];
        [async start];
    }
    
}

-(void)uninstallModule:(NSString*)identifier{

    CubeModel* model=[[DataCenter defaultCenter] finidInstallCubeModule:identifier];
    if(model!=nil){
        NSString* wwwPath = [IsolatedStorageFile cubeModuleIdentifierRoot:model.identifier];
        
        [[NSFileManager defaultManager] removeItemAtPath:wwwPath error:nil];
        
        
        BOOL running=NO;
        model.status = CubeMoudleStatusNone;
        for (CubeModuleWorkTask* async in asyncs){
            if ([async.cubeModel.identifier isEqualToString:model.identifier]){
                running=async.running;
                async.callback = nil;
                [async cancel];
                [asyncs removeObject:async];
                [[NSNotificationCenter defaultCenter] postNotificationName:CubeModuleDownloadingFailed object:model];
                break;
            }
        }
        
        
        NSDictionary* dict=[NSDictionary dictionaryWithObjectsAndKeys:
                            model.identifier,@"identifier",
                            [CubeModuleParser serialize:model showOutputIcon:YES],@"moduleMessage",
                            @"uninstall",@"type",
                            nil];
        
        [[DataCenter defaultCenter].installMoudules removeObject:model];
        [self saveLocalModuleList];
        asyncIsDownloaded=NO;
        if(running && [asyncs count]>0){
            CubeModuleWorkTask* async=[asyncs objectAtIndex:0];
            [async start];
            asyncIsDownloaded = YES;
        }
        
        
        [[NSNotificationCenter defaultCenter] postNotificationName:CubeRefreshModule object:dict];
        [[NSNotificationCenter defaultCenter] postNotificationName:CubeRefreshMainPage object:dict];
    }
}

-(void)updateModule:(NSString*)identifier{
    NSMutableArray* installMoudules = [[DataCenter defaultCenter] installMoudules];
    for (CubeModel* model in installMoudules){
        if ([model.identifier isEqualToString:identifier]){
            model.status = CubeMoudleStatusUpdating;
            model.downloadedProcess = 0;
            model.downloadedTotalCount = 100;
            [self saveLocalModuleList];
            CubeModuleWorkTask* async = [[CubeModuleWorkTask alloc] init];
            async.action = CubeModuleWorkTaskActionUpdate;
            
            async.callback = self;
            async.cubeModel=model;
            [asyncs addObject:async];
            async = nil;
            break;
        }
    }
    
    if (!asyncIsDownloaded){
        asyncIsDownloaded = YES;
        CubeModuleWorkTask* async=[asyncs objectAtIndex:0];
        [async start];
    }

}

#pragma mark ICubeModuleWorkTask delegate



-(void)process:(CubeModuleWorkTask*)sync{
    NSMutableArray* installMoudules = [[DataCenter defaultCenter] installMoudules];

    for (CubeModel* model in installMoudules){
        if ([model.identifier isEqualToString:sync.cubeModel.identifier]){
            model.downloadedProcess=sync.cubeModel.downloadedProcess;
            model.downloadedTotalCount = sync.cubeModel.downloadedTotalCount;
            break;
        }
    }
    
    if (sync.cubeModel.downloadedTotalCount == 0)
        return;
    
    long total = sync.cubeModel.downloadedTotalCount;
    long progress =  sync.cubeModel.downloadedProcess;
    
    
    double count = (double)(((double)progress / (double)total) * 100);
    //发送进度通知browser刷新模块进度条
    NSDictionary* dict=[NSDictionary dictionaryWithObjectsAndKeys:
                        sync.cubeModel.identifier,@"identifier",
                        [NSNumber numberWithInt:count],@"count",
                        nil];    
    //在模块详情页面刷新进度条
    
    [[NSNotificationCenter defaultCenter] postNotificationName:CubeModuleDownloadingProcess object:dict];

    [[NSNotificationCenter defaultCenter] postNotificationName:CubeUpdateProgress object:dict];
}

-(void) success:(CubeModuleWorkTask*)sync{
    sync.callback = nil;
    [sync cancel];
    
    NSMutableArray* installMoudules = [[DataCenter defaultCenter] installMoudules];
    
    for (CubeModel* model in installMoudules){
        if ([model.identifier isEqualToString:sync.cubeModel.identifier]){
            if (model.status == CubeMoudleStatusUpdating){
                NSArray* serviceModules=[DataCenter defaultCenter].serviceModules;
                for (CubeModel* _model in serviceModules){
                    if ([_model.identifier isEqualToString:model.identifier]){
                        model.build = _model.build;
                        model.version = _model.version;
                        break;
                    }
                }
            }
            model.status = CubeMoudleStatusFinish;
            break;
        }
        }
    
    sync.cubeModel.status = CubeMoudleStatusFinish;
    [self saveLocalModuleList];
    
    NSString* serializer=[CubeModuleParser serialize:sync.cubeModel showOutputIcon:YES];
    
    //管理页面中模块的增减
    NSDictionary* dict=[NSDictionary dictionaryWithObjectsAndKeys:
                        (sync.action == CubeModuleWorkTaskActionInstall ? @"install" : @"upgrade"),@"type",
                        sync.cubeModel.identifier,@"identifier",
                        serializer,@"moduleMessage",
                        nil];

    [asyncs removeObject:sync];

    
    [[NSNotificationCenter defaultCenter] postNotificationName:CubeRefreshModule object:dict];
    
    [[NSNotificationCenter defaultCenter] postNotificationName:CubeModuleDownloadingSuccess object:dict];

    
    //刷新主页面
    dict=[NSDictionary dictionaryWithObjectsAndKeys:
          @"main",@"type",
          sync.cubeModel.identifier,@"identifier",
          serializer,@"moduleMessage",
          nil];
    [[NSNotificationCenter defaultCenter] postNotificationName:CubeRefreshMainPage object:dict];

    

    asyncIsDownloaded = NO;
    if ([asyncs count]>0){
        sync=[asyncs objectAtIndex:0];
        [sync start];
        asyncIsDownloaded = YES;
    }
}


-(void) failed:(CubeModuleWorkTask*)sync{
    sync.callback = nil;
    [sync cancel];
    
    NSMutableArray* installMoudules = [[DataCenter defaultCenter] installMoudules];
    
    for (CubeModel* model in installMoudules){
        if ([model.identifier isEqualToString:sync.cubeModel.identifier]){
            if (model.status == CubeMoudleStatusUpdating){
                model.status = CubeMoudleStatusFinish;
            }
            else{
                [installMoudules removeObject:model];
            }
            break;
        }
    }
    [self saveLocalModuleList];
    
    NSDictionary* dict=[NSDictionary dictionaryWithObjectsAndKeys:
                        sync.cubeModel.identifier,@"identifier",
                        [CubeModuleParser serialize:sync.cubeModel showOutputIcon:YES],@"moduleMessage",
                        @"main",@"type",
                        [NSNumber numberWithInt:101],@"count",
                        nil];

    [asyncs removeObject:sync];
    
    
    //刷新主界面，并隐藏进度条
    [[NSNotificationCenter defaultCenter] postNotificationName:CubeUpdateProgress object:dict];
    
    [[NSNotificationCenter defaultCenter] postNotificationName:CubeModuleDownloadingFailed object:dict];


    [[NSNotificationCenter defaultCenter] postNotificationName:CubeRefreshMainPage object:dict];


    asyncIsDownloaded = NO;
    if ([asyncs count]>0){
        sync=[asyncs objectAtIndex:0];
        [sync start];
        asyncIsDownloaded = YES;
    }
}


@end
